package com.pt.service.impl;

import com.pt.dto.response.AuthResponse;
import com.pt.entity.User;
import com.pt.security.JwtTokenProvider;
import com.pt.service.EmailService;
import com.pt.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

@Service
@RequiredArgsConstructor
@Slf4j
public class EmailServiceImpl implements EmailService {
    
    private final JavaMailSender mailSender;
    private final PasswordEncoder passwordEncoder;
    private final JwtTokenProvider tokenProvider;
    private final UserDetailsService userDetailsService;
    @Lazy
    private final UserService userService;
    
    @Value("${spring.mail.username:noreply@pt.com}")
    private String fromEmail;
    
    // 邮箱验证码缓存，实际项目中应使用Redis
    private final Map<String, EmailVerification> verificationCache = new ConcurrentHashMap<>();
    
    @Override
    public void sendRegistrationVerificationEmail(Long userId, String email, String username) {
        String code = generateVerificationCode();
        
        // 保存验证码
        verificationCache.put(code, new EmailVerification(userId, email, "REGISTRATION", LocalDateTime.now().plusHours(24)));
        
        String subject = "欢迎注册PT站 - 邮箱验证";
        String content = String.format(
            "亲爱的 %s，\n\n" +
            "欢迎注册我们的PT站！\n\n" +
            "您的邮箱验证码是：【%s】\n\n" +
            "请在注册页面输入上述6位验证码完成邮箱验证。\n\n" +
            "验证码有效期为24小时，请尽快使用。\n\n" +
            "如果您没有注册此账号，请忽略此邮件。\n\n" +
            "祝您使用愉快！\n" +
            "PT站管理团队",
            username, code
        );
        
        sendEmail(email, subject, content);
        log.info("注册验证邮件已发送至: {}", email);
    }
    
    @Override
    public void sendPasswordResetEmail(Long userId, String email, String username) {
        String code = generateVerificationCode();
        
        // 保存验证码
        verificationCache.put(code, new EmailVerification(userId, email, "PASSWORD_RESET", LocalDateTime.now().plusHours(1)));
        
        String subject = "PT站密码重置";
        String content = String.format(
            "亲爱的 %s，\n\n" +
            "您请求重置PT站账号密码。\n\n" +
            "您的密码重置验证码是：【%s】\n\n" +
            "请复制上述6位验证码，在重置密码页面中输入。\n" +
            "验证码有效期为1小时，请尽快使用。\n\n" +
            "如果您没有申请密码重置，请忽略此邮件。\n\n" +
            "PT站管理团队",
            username, code
        );
        
        sendEmail(email, subject, content);
        log.info("密码重置邮件已发送至: {}", email);
    }
    
    @Override
    public boolean verifyEmail(String code) {
        EmailVerification verification = verificationCache.get(code);
        if (verification == null || verification.isExpired()) {
            return false;
        }
        
        if (!"REGISTRATION".equals(verification.getType())) {
            return false;
        }
        
        // 激活用户账号
        User user = userService.getById(verification.getUserId());
        if (user != null) {
            user.setStatus(1); // 设为正常状态
            userService.updateById(user);
        }
        
        // 删除验证码
        verificationCache.remove(code);
        return true;
    }
    
    @Override
    public AuthResponse verifyEmailAndCompleteRegistration(String code) {
        EmailVerification verification = verificationCache.get(code);
        if (verification == null || verification.isExpired()) {
            throw new RuntimeException("验证码无效或已过期");
        }
        
        if (!"REGISTRATION".equals(verification.getType())) {
            throw new RuntimeException("验证码类型错误");
        }
        
        // 激活用户账号
        User user = userService.getById(verification.getUserId());
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        user.setStatus(1); // 设为正常状态
        userService.updateById(user);
        
        // 生成JWT token完成注册
        try {
            UserDetails userDetails = userDetailsService.loadUserByUsername(user.getUsername());
            UsernamePasswordAuthenticationToken authentication = 
                    new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            
            String token = tokenProvider.generateToken(authentication);
            
            // 删除验证码
            verificationCache.remove(code);
            
            return new AuthResponse(token, "邮箱验证成功，注册完成");
        } catch (Exception e) {
            log.error("生成JWT token失败", e);
            throw new RuntimeException("注册完成失败，请重试");
        }
    }
    
    @Override
    public boolean resetPassword(String code, String newPassword) {
        EmailVerification verification = verificationCache.get(code);
        if (verification == null || verification.isExpired()) {
            return false;
        }
        
        if (!"PASSWORD_RESET".equals(verification.getType())) {
            return false;
        }
        
        // 重置密码
        User user = userService.getById(verification.getUserId());
        if (user != null) {
            user.setPassword(passwordEncoder.encode(newPassword));
            userService.updateById(user);
        }
        
        // 删除验证码
        verificationCache.remove(code);
        return true;
    }
    
    @Override
    public void sendNotificationEmail(String email, String subject, String content) {
        sendEmail(email, subject, content);
    }
    
    private void sendEmail(String to, String subject, String content) {
        try {
            SimpleMailMessage message = new SimpleMailMessage();
            message.setFrom(fromEmail);
            message.setTo(to);
            message.setSubject(subject);
            message.setText(content);
            
            mailSender.send(message);
            log.info("邮件发送成功: {} -> {}", subject, to);
        } catch (Exception e) {
            log.error("邮件发送失败: {} -> {}", subject, to, e);
        }
    }
    
    private String generateVerificationCode() {
        // 6位数字+字母组合验证码
        String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        StringBuilder code = new StringBuilder();
        java.util.Random random = new java.util.Random();
        
        for (int i = 0; i < 6; i++) {
            code.append(chars.charAt(random.nextInt(chars.length())));
        }
        
        return code.toString();
    }
    
    private static class EmailVerification {
        private final Long userId;
        private final String email;
        private final String type;
        private final LocalDateTime expireTime;
        
        public EmailVerification(Long userId, String email, String type, LocalDateTime expireTime) {
            this.userId = userId;
            this.email = email;
            this.type = type;
            this.expireTime = expireTime;
        }
        
        public Long getUserId() { return userId; }
        public String getEmail() { return email; }
        public String getType() { return type; }
        public boolean isExpired() { return LocalDateTime.now().isAfter(expireTime); }
    }
} 